#ifndef THREADPOOL_HPP
#define THREADPOOL_HPP
#include <pthread.h>
#include <unistd.h>

#include <iostream>
#include <queue>
#include <string>
#include <vector>

// 线程信息结构体，存储线程ID和名称
struct ThreadInfo {
  pthread_t tid;
  std::string name;
};

template <class T>
class ThreadPool {
  // 默认线程池大小
  const static int defaultnum = 7;

 private:
  // 锁定互斥锁
  void Lock() { pthread_mutex_lock(&mutex_); }

  // 解锁互斥锁
  void Unlock() { pthread_mutex_unlock(&mutex_); }

  // 唤醒等待的线程
  void Wake() { pthread_cond_signal(&cond_); }

  // 等待条件变量
  void Wait() { pthread_cond_wait(&cond_, &mutex_); }

  // 检查任务队列是否为空
  bool Isempty() { return tasks_.empty(); }

 public:
  // 根据线程ID获取线程名称
  std::string Getname(pthread_t tid) {
    for (const auto &ti : threads_) {
      if (ti.tid == tid) {
        return ti.name;
      }
    }
    return "null";
  }

 public:
  // 启动线程池中的所有线程
  void Start() {
    int num = threads_.size();
    for (int i = 0; i < num; ++i) {
      threads_[i].name = "Thread-" + std::to_string(i);
      pthread_create(&(threads_[i].tid), nullptr, HanderTask, this);
    }
  }

  // 向任务队列添加任务
  void Push(const T &t) {
    Lock();
    tasks_.push(t);
    Wake();
    Unlock();
  }

  // 从任务队列取出任务
  T Pop() {
    T t = tasks_.front();
    tasks_.pop();
    return t;
  }

  // 线程处理任务的静态函数
  static void *HanderTask(void *args) {
    ThreadPool<T> *tp = static_cast<ThreadPool<T> *>(args);
    std::string name = tp->Getname(pthread_self());
    while (1) {
      tp->Lock();
      while (tp->Isempty()) {
        tp->Wait();
      }
      T t = tp->Pop();
      tp->Unlock();

      // 执行任务并打印结果
      t();
    }

    return nullptr;
  }

  // 获取线程池单例实例
  static ThreadPool<T> *getInstance(int volume = defaultnum) {
    if (nullptr == Tp_) {
      std::cout << "The instance load first..." << std::endl;
      pthread_mutex_lock(&lock_);
      if (nullptr == Tp_) {
        Tp_ = new ThreadPool<T>(volume);
      }
      pthread_mutex_unlock(&lock_);
    }
    return Tp_;
  }

 private:
  // 私有构造函数，实现单例模式
  ThreadPool(int volume = defaultnum) : threads_(volume) {
    pthread_mutex_init(&mutex_, nullptr);
    pthread_cond_init(&cond_, nullptr);
  }

  // 析构函数
  ~ThreadPool() {
    pthread_mutex_destroy(&mutex_);
    pthread_cond_destroy(&cond_);
  }

 private:
  // 禁用拷贝构造和赋值操作符
  const ThreadPool<T> &operator=(const ThreadPool<T> &&) = delete;
  ThreadPool(const ThreadPool<T> &&) = delete;

 private:
  std::vector<ThreadInfo> threads_;  // 存储线程信息的向量
  std::queue<T> tasks_;              // 任务队列

  pthread_mutex_t mutex_;  // 互斥锁
  pthread_cond_t cond_;    // 条件变量

  static ThreadPool<T> *Tp_;  // 单例指针

  static pthread_mutex_t lock_;  // 用于保护单例创建的静态互斥锁
};

// 初始化静态成员
template <class T>
ThreadPool<T> *ThreadPool<T>::Tp_ = nullptr;

template <class T>
pthread_mutex_t ThreadPool<T>::lock_ = PTHREAD_MUTEX_INITIALIZER;

#endif
